const schedule = require('node-schedule');
const wechatService = require('./wechatService');
const weatherService = require('./weatherService');
const db = require('../models');

class ScheduleService {
  constructor() {
    this.jobs = {};
  }

  // 初始化所有定时任务
  async initAllSchedules() {
    const subscriptions = await db.Subscription.findAll({
      where: { status: 1 },
      include: [{ model: db.User, attributes: ['openid'] }]
    });

    subscriptions.forEach(sub => {
      this.createSchedule(sub);
    });
  }

  // 创建单个订阅的定时任务
  createSchedule(subscription) {
    const { id, userId, cityCode, cityName, pushTime, weatherEnabled, trafficEnabled, customContent } = subscription;
    const [hour, minute] = pushTime.split(':').map(Number);
    
    const rule = new schedule.RecurrenceRule();
    rule.hour = hour;
    rule.minute = minute;
    rule.tz = 'Asia/Shanghai';

    // 并发控制
    const MAX_CONCURRENT_JOBS = 5;
    let activeJobs = 0;
    const jobQueue = [];

    this.jobs[id] = schedule.scheduleJob(rule, async () => {
      if (activeJobs >= MAX_CONCURRENT_JOBS) {
        jobQueue.push(() => this.executePushTask(subscription));
        return;
      }

      activeJobs++;
      try {
        await this.executePushTask(subscription);
      } catch (err) {
        logger.error(`定时任务执行失败 - 订阅ID: ${id}`, {
          error: err.message,
          stack: err.stack
        });
      } finally {
        activeJobs--;
        if (jobQueue.length > 0) {
          const nextJob = jobQueue.shift();
          nextJob();
        }
      }
    });
  }

  // 执行推送任务
  async executePushTask(subscription) {
    const { id, userId, cityCode, weatherEnabled, trafficEnabled, customContent } = subscription;
    const startTime = Date.now();
    
    try {
      // 获取用户信息
      const user = await db.User.findByPk(userId);
      if (!user || user.status !== 1) return;

      // 检查推送权限
      if (!user.pushEnabled) {
        logger.info('定时推送跳过：用户已禁用推送', { userId });
        return;
      }

      // 检查免打扰时段
      if (this.isQuietHours(user)) {
        logger.info('定时推送跳过：处于免打扰时段', { userId });
        return;
      }

      // 准备要发送的消息数组
      const messages = [];
      
      // 天气推送
      if (weatherEnabled) {
        const weatherData = await weatherService.getWeather(cityCode);
        messages.push({
          templateId: wechatService.config.wechat.templateIds.weather,
          data: this.formatWeatherData(weatherData)
        });
      }
      
      // 限行推送
      if (trafficEnabled) {
        const trafficData = await this.getTrafficInfo(cityCode);
        messages.push({
          templateId: wechatService.config.wechat.templateIds.traffic,
          data: this.formatTrafficData(trafficData)
        });
      }
      
      // 自定义内容推送
      if (customContent) {
        messages.push({
          templateId: wechatService.config.wechat.templateIds.custom,
          data: this.formatCustomContent(customContent)
        });
      }
      
      // 发送所有消息
      for (const message of messages) {
        await wechatService.sendTemplateMessage(
          user.openid,
          message.templateId,
          message.data
        );
      }

      // 记录任务执行时间
      const duration = Date.now() - startTime;
      logger.info('定时任务执行成功', {
        subscriptionId: id,
        userId,
        duration: `${duration}ms`
      });
    } catch (err) {
      const duration = Date.now() - startTime;
      logger.error('定时任务执行失败', {
        subscriptionId: id,
        userId,
        duration: `${duration}ms`,
        error: err.message,
        stack: err.stack
      });
      throw err;
    }
  }

  // 检查是否处于免打扰时段
  isQuietHours(user) {
    if (!user.quietHoursEnabled) return false;

    const now = new Date();
    const [startHour, startMin] = user.quietHoursStart.split(':').map(Number);
    const [endHour, endMin] = user.quietHoursEnd.split(':').map(Number);

    const startTime = new Date();
    startTime.setHours(startHour, startMin, 0, 0);

    const endTime = new Date();
    endTime.setHours(endHour, endMin, 0, 0);

    return now >= startTime && now <= endTime;
  }

  // 获取限行信息
  async getTrafficInfo(cityCode) {
    // 这里应调用限行信息API
    // 目前返回模拟数据
    return {
      city: cityCode,
      date: new Date().toLocaleDateString(),
      restriction: Math.floor(Math.random() * 10) + '和' + Math.floor(Math.random() * 10),
      updateTime: new Date().toISOString()
    };
  }

  // 格式化限行数据
  formatTrafficData(data) {
    return {
      first: {
        value: `${data.city}今日限行信息`,
        color: '#173177'
      },
      keyword1: {
        value: data.date,
        color: '#173177'
      },
      keyword2: {
        value: data.restriction,
        color: '#FF0000'
      },
      keyword3: {
        value: '全天',
        color: '#173177'
      },
      remark: {
        value: '请合理安排出行计划',
        color: '#173177'
      }
    };
  }

  // 格式化自定义内容
  formatCustomContent(content) {
    return {
      first: {
        value: '您的自定义内容推送',
        color: '#173177'
      },
      keyword1: {
        value: new Date().toLocaleDateString(),
        color: '#173177'
      },
      keyword2: {
        value: content,
        color: '#173177'
      },
      remark: {
        value: '来自智慧生活推送服务',
        color: '#173177'
      }
    };
  }

  // 格式化天气数据为微信模板消息格式
  formatWeatherData(data) {
    const today = data.casts[0];
    const tomorrow = data.casts[1];
    
    return {
      first: {
        value: `${data.city}天气预报`,
        color: '#173177'
      },
      keyword1: {
        value: today.date,
        color: '#173177'
      },
      keyword2: {
        value: `${today.dayWeather}转${today.nightWeather}`,
        color: '#173177'
      },
      keyword3: {
        value: `${today.dayTemp}℃ ~ ${today.nightTemp}℃`,
        color: '#173177'
      },
      keyword4: {
        value: `${today.dayWind}风${today.dayPower}级`,
        color: '#173177'
      },
      remark: {
        value: `明天${tomorrow.dayWeather}，${tomorrow.dayTemp}℃ ~ ${tomorrow.nightTemp}℃`,
        color: '#173177'
      }
    };
  }
}

module.exports = new ScheduleService();